using System;
using System.Collections.Specialized;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MetaBuilders.Irc;
using MetaBuilders.Irc.Messages;

namespace MetaBuilders.NeboTests
{

	[TestClass]
	public class WatchTests : MessageTester
	{

		[TestMethod]
		public void Watch600Test()
		{
			String[] raws = new String[] {
				":hotspeed.sg.as.dal.net 600 artificer ImNotHere * * 0 :logged offline"
			};

			foreach ( String raw in raws )
			{
				AssertRoundTripAndType( raw, typeof( WatchedUserNowOfflineMessage ) );
			}

			WatchedUserNowOfflineMessage msg;

			msg = MessageParserService.Service.Parse( raws[ 0 ] ) as WatchedUserNowOfflineMessage;
			Assert.AreEqual( msg.WatchedUser.Nick, "ImNotHere" );
			Assert.AreEqual( msg.WatchedUser.UserName, "*" );
			Assert.AreEqual( msg.WatchedUser.HostName, "*" );
			Assert.AreEqual( MessageUtil.ConvertToUnixTime( msg.TimeOfChange ), 0 );
		}

		[TestMethod]
		public void Watch601Test()
		{
			String[] raws = new String[] {
				":hotspeed.sg.as.dal.net 601 artificer artificer artificer c-24-8-243-76.client.comcast.net 1082383302 :logged online"
			};

			foreach ( String raw in raws )
			{
				AssertRoundTripAndType( raw, typeof( WatchedUserNowOnlineMessage ) );
			}

			WatchedUserNowOnlineMessage msg;

			msg = MessageParserService.Service.Parse( raws[ 0 ] ) as WatchedUserNowOnlineMessage;
			Assert.AreEqual( msg.WatchedUser.Nick, "artificer" );
			Assert.AreEqual( msg.WatchedUser.UserName, "artificer" );
			Assert.AreEqual( msg.WatchedUser.HostName, "c-24-8-243-76.client.comcast.net" );
			Assert.AreEqual( MessageUtil.ConvertToUnixTime( msg.TimeOfChange ), 1082383302 );
		}

		[TestMethod]
		public void Watch602Test()
		{
			String[] raws = new String[] {
											 ":hotspeed.sg.as.dal.net 602 artificer art * * 0 :stopped watching",
											 ":hotspeed.sg.as.dal.net 602 artificer artificer artificer c-24-8-243-76.client.comcast.net 1082383544 :stopped watching",
											 ":hotspeed.sg.as.dal.net 602 artificer artificer artificer c-24-8-243-76.client.comcast.net 1082383572 :stopped watching"
										 };

			foreach ( String raw in raws )
			{
				AssertRoundTripAndType( raw, typeof( WatchStoppedMessage ) );
			}

			WatchStoppedMessage msg;

			msg = MessageParserService.Service.Parse( raws[ 0 ] ) as WatchStoppedMessage;
			Assert.AreEqual( msg.WatchedUser.Nick, "art" );
			Assert.AreEqual( msg.WatchedUser.UserName, "*" );
			Assert.AreEqual( msg.WatchedUser.HostName, "*" );
			Assert.AreEqual( MessageUtil.ConvertToUnixTime( msg.TimeOfChange ), 0 );

			msg = MessageParserService.Service.Parse( raws[ 1 ] ) as WatchStoppedMessage;
			Assert.AreEqual( msg.WatchedUser.Nick, "artificer" );
			Assert.AreEqual( msg.WatchedUser.UserName, "artificer" );
			Assert.AreEqual( msg.WatchedUser.HostName, "c-24-8-243-76.client.comcast.net" );
			Assert.AreEqual( MessageUtil.ConvertToUnixTime( msg.TimeOfChange ), 1082383544 );

			msg = MessageParserService.Service.Parse( raws[ 2 ] ) as WatchStoppedMessage;
			Assert.AreEqual( msg.WatchedUser.Nick, "artificer" );
			Assert.AreEqual( msg.WatchedUser.UserName, "artificer" );
			Assert.AreEqual( msg.WatchedUser.HostName, "c-24-8-243-76.client.comcast.net" );
			Assert.AreEqual( MessageUtil.ConvertToUnixTime( msg.TimeOfChange ), 1082383572 );

		}

		[TestMethod]
		public void Watch603Test()
		{
			String[] raws = new String[] {
											 ":hotspeed.sg.as.dal.net 603 artificer :You have 0 and are on 0 WATCH entries",
											 ":hotspeed.sg.as.dal.net 603 artificer :You have 1 and are on 1 WATCH entries"
										 };

			foreach ( String raw in raws )
			{
				AssertRoundTripAndType( raw, typeof( WatchStatusReplyMessage ) );
			}

			WatchStatusReplyMessage msg;

			msg = MessageParserService.Service.Parse( raws[ 0 ] ) as WatchStatusReplyMessage;
			Assert.AreEqual( msg.WatchListCount, 0 );
			Assert.AreEqual( msg.UsersWatchingYou, 0 );

			msg = MessageParserService.Service.Parse( raws[ 1 ] ) as WatchStatusReplyMessage;
			Assert.AreEqual( msg.WatchListCount, 1 );
			Assert.AreEqual( msg.UsersWatchingYou, 1 );
		}

		[TestMethod]
		public void Watch604Test()
		{
			String[] raws = new String[] {
											 ":hotspeed.sg.as.dal.net 604 artificer artificer artificer c-24-8-243-76.client.comcast.net 1082383302 :is online"
										 };

			foreach ( String raw in raws )
			{
				AssertRoundTripAndType( raw, typeof( WatchedUserIsOnlineMessage ) );
			}

			WatchedUserIsOnlineMessage msg;

			msg = MessageParserService.Service.Parse( raws[ 0 ] ) as WatchedUserIsOnlineMessage;
			Assert.AreEqual( msg.WatchedUser.Nick, "artificer" );
			Assert.AreEqual( msg.WatchedUser.UserName, "artificer" );
			Assert.AreEqual( msg.WatchedUser.HostName, "c-24-8-243-76.client.comcast.net" );
			Assert.AreEqual( MessageUtil.ConvertToUnixTime( msg.TimeOfChange ), 1082383302 );

		}

		[TestMethod]
		public void Watch605Test()
		{
			String[] raws = new String[] {
											 ":hotspeed.sg.as.dal.net 605 artificer ImNotHere * * 0 :is offline"
										 };

			foreach ( String raw in raws )
			{
				AssertRoundTripAndType( raw, typeof( WatchedUserIsOfflineMessage ) );
			}

			WatchedUserIsOfflineMessage msg;

			msg = MessageParserService.Service.Parse( raws[ 0 ] ) as WatchedUserIsOfflineMessage;
			Assert.AreEqual( msg.WatchedUser.Nick, "ImNotHere" );
			Assert.AreEqual( msg.WatchedUser.UserName, "*" );
			Assert.AreEqual( msg.WatchedUser.HostName, "*" );

		}

		[TestMethod]
		public void Watch606Test()
		{
			String[] raws = new String[] {
				":mesra.kl.my.dal.net 606 artificer :nebobot2 nebobot"
			};

			foreach ( String raw in raws )
			{
				AssertRoundTripAndType( raw, typeof( WatchStatusNicksReplyMessage ) );
			}

			WatchStatusNicksReplyMessage msg;

			msg = MessageParserService.Service.Parse( raws[ 0 ] ) as WatchStatusNicksReplyMessage;
			Assert.AreEqual( 2, msg.Nicks.Count );
			Assert.AreEqual( "nebobot2", msg.Nicks[ 0 ]);
			Assert.AreEqual( "nebobot", msg.Nicks[ 1 ] );
		}

		[TestMethod]
		public void Watch607Test()
		{
			String[] raws = new String[] {
											 ":hotspeed.sg.as.dal.net 607 artificer :End of WATCH l",
											 ":hotspeed.sg.as.dal.net 607 artificer :End of WATCH L",
											 ":hotspeed.sg.as.dal.net 607 artificer :End of WATCH s"
										 };

			foreach ( String raw in raws )
			{
				AssertRoundTripAndType( raw, typeof( WatchListEndReplyMessage ) );
			}

			WatchListEndReplyMessage msg;

			msg = MessageParserService.Service.Parse( raws[ 0 ] ) as WatchListEndReplyMessage;
			Assert.AreEqual( msg.ListType, "l" );

			msg = MessageParserService.Service.Parse( raws[ 1 ] ) as WatchListEndReplyMessage;
			Assert.AreEqual( msg.ListType, "L" );

			msg = MessageParserService.Service.Parse( raws[ 2 ] ) as WatchListEndReplyMessage;
			Assert.AreEqual( msg.ListType, "s" );

		}

		[TestMethod]
		public void WatchClearTest()
		{
			String raw = ":hotspeed.sg.as.dal.net WATCH C";

			AssertRoundTripAndType( raw, typeof( WatchListClearMessage ) );
		}

		[TestMethod]
		public void WatchStatsTest()
		{
			String raw = ":hotspeed.sg.as.dal.net WATCH S";

			AssertRoundTripAndType( raw, typeof( WatchStatusRequestMessage ) );
		}

		[TestMethod]
		public void WatchListTest()
		{
			String[] raws = new String[] {
										   ":hotspeed.sg.as.dal.net WATCH l",
										   ":hotspeed.sg.as.dal.net WATCH L"
									   };

			foreach ( String raw in raws )
			{
				AssertRoundTripAndType( raw, typeof( WatchListRequestMessage ) );
			}

			WatchListRequestMessage msg;

			msg = MessageParserService.Service.Parse( raws[ 0 ] ) as WatchListRequestMessage;
			Assert.IsTrue( msg.OnlineOnly );

			msg = MessageParserService.Service.Parse( raws[ 1 ] ) as WatchListRequestMessage;
			Assert.IsFalse( msg.OnlineOnly );
		}

		[TestMethod]
		public void WatchEditorTest()
		{
			String[] raws = new String[] {
											 ":hotspeed.sg.as.dal.net WATCH +artificer +foo",
											 ":hotspeed.sg.as.dal.net WATCH +ImNotHere",
											 ":hotspeed.sg.as.dal.net WATCH -art"
										 };

			foreach ( String raw in raws )
			{
				AssertRoundTripAndType( raw, typeof( WatchListEditorMessage ) );
			}

			WatchListEditorMessage msg;

			msg = MessageParserService.Service.Parse( raws[ 0 ] ) as WatchListEditorMessage;
			Assert.AreEqual( msg.AddedNicks.Count, 2 );
			Assert.AreEqual( msg.RemovedNicks.Count, 0 );
			Assert.AreEqual( msg.AddedNicks[ 0 ], "artificer" );
			Assert.AreEqual( msg.AddedNicks[ 1 ], "foo" );


			msg = MessageParserService.Service.Parse( raws[ 1 ] ) as WatchListEditorMessage;
			Assert.AreEqual( msg.AddedNicks.Count, 1 );
			Assert.AreEqual( msg.RemovedNicks.Count, 0 );
			Assert.AreEqual( msg.AddedNicks[ 0 ], "ImNotHere" );

			msg = MessageParserService.Service.Parse( raws[ 2 ] ) as WatchListEditorMessage;
			Assert.AreEqual( msg.AddedNicks.Count, 0 );
			Assert.AreEqual( msg.RemovedNicks.Count, 1 );
			Assert.AreEqual( msg.RemovedNicks[ 0 ], "art" );
		}


	}
}
